/**
 * WTF Engine
 *
 * License... etc.
 **
 * GUI Window Manager
 * 
 * The WTF Engine GUI Window System/Manager. Windows are built
 * from Widgets, which build on top of Overlays.
 * 
 * Provides:
 * 	- Window class
 *  - Window Manager and the State Controller
 * 
 * Specifications:
 * 	- Coordinates are specified in positive pixels
 *  - top left corner is (0,0)
 * 
 * \sa		WtfEngine::Overlay
 **
 * Authors: Sean Micklethwaite, Mac Duy Hai
 **/

#ifndef __gui_windowH__
#define __gui_windowH__

#include "gui_widgets.h"
#include "input.h"
#include "trigger.h"

namespace WtfGui {
	class IWindowContainer: public virtual WtfEngine::IGcObject {
		public:
			virtual WidgetContainer::tRef getWindowDock() const = 0;
	};

	/**
	 * Window Class.
	 * 
	 * An advanced widget which can contain child widgets and has a title bar.
	 */
	class Window : public IWindowContainer, public WidgetContainer {
		private:
			class Titlebar : public Widgets::Label
			{
			public:
				Titlebar(const WtfEngine::String& sCaption) : Widgets::Label(sCaption,
						 tFont::Get("v_gui_font"), false) {};
				
				// Define these to pass events to parent window
				virtual bool OnMouseDown(const iVector2D& vPos, WtfEngine::tMouseButton btn){
					return mpParent->OnMouseDown(vPos + getPosition(), btn);
				};
				
				virtual bool OnMouseUp(const iVector2D& vPos, WtfEngine::tMouseButton btn){
					return mpParent->OnMouseUp(vPos + getPosition(), btn);
				};
				
				DATA_OBJECT(Titlebar, sizeof(Titlebar));
			};
			
			Titlebar::tRef				mTitlebar;		///< Window Title Bar (with title)
			Widgets::Button::tRef		mCloseButton;
			Widgets::Button::tRef		mDockButton;
			WtfEngine::String			msTitle;		///< Window Title. (deprecated?)
			
			bool						mbDocked, mbSizeX, mbSizeY;
			void Paint(float d);
			
		public:	
			Window(const WtfEngine::String& sTitle);
			
			virtual void Dock();
			virtual void Undock();
			void DockToggle();


			/**** Event handlers ****/
			
			virtual void OnResize();
			
			virtual bool OnMouseDown(const iVector2D& vPos, WtfEngine::tMouseButton btn);
			virtual bool OnMouseUp(const iVector2D& vPos, WtfEngine::tMouseButton btn);
			virtual bool OnMouseMove(const iVector2D& vPos, const iVector2D& vDelta);
			
			virtual void OnClose();
	
			virtual WidgetContainer::tRef getWindowDock() const;

			/// Reference
			typedef WtfEngine::GcReference<Window>	tRef;
	};


	class ScreenOverlay : public WidgetContainer {
		iVector2D mScreenPos;

		// Input handlers
		void KeyPress();
		void MouseDown();
		void MouseUp();
		void MouseMove();

		void OnScreenResize();

	public:
		ScreenOverlay();
		virtual ~ScreenOverlay();

		virtual void Paint(float d);

		void AddWindow(const Window::tRef& rW, bool setActv = true){
			AddChild(rW);
			if(setActv){ 
				Select(rW);
				SendToFront(rW);
			};
		};

		void Init();
		virtual void Remove();

		GC_AUTOSIZE(ScreenOverlay);
	};


	/**
	 * Window Manager.
	 * 
	 * Puts a dark overlay over the current scene and manages windows reported to it. It 
	 * takes care of the state switching (game/console) and sends keypress events to the
	 * current active window.
	 */
	class WindowManager : public IWindowContainer, public ScreenOverlay {
		private:
			bool					isActive;
	
			WtfEngine::Event::tRef		mrToggleEvent;
			WidgetContainer::tRef		mrWindowDock;
			
			WtfEngine::Interpolated<fVector4D, WtfEngine::Functions<fVector4D>::Linear> mBgColour;

		public:
			WindowManager();
		
			/// Draws backdrop, sets coordinates and draws all windows
			void Paint(float d);
	

			void BindToEvent(WtfEngine::Event* ev = NULL);
			/// toggles game state
			void WmToggle();
			/// Actually removes the GUI
			void WmClose();
			
			void WmSetActive(bool b);
	
			virtual WidgetContainer::tRef getWindowDock() const {
				return mrWindowDock;
			};
			void setWindowDock(const WidgetContainer::tRef& rDock) {
				mrWindowDock = rDock;
			};

			bool isSelected() {
				return isActive;
			};
			
			/// Receives keypress and invokes the keypress handler 
			/// of the current window. Sends unicode char code.
			virtual bool OnKeyPress(int key, int flags);
			
			template <class T>
			void Spawn(){
				AddWindow(new T());
			};

			GC_AUTOSIZE(WindowManager);
	};

	/**
	 * Window Manager Game State Controller.
	 * 
	 * Controls the current state of the game and displays the WM as appropriate.
	 */
	class WmGameState : public WtfEngine::GameState	{
		private:
			WtfEngine::GcReference<WindowManager>	mrWinMgr;
	
		protected:
			void Enable();
			void Disable();
			
		public:
			WmGameState(WindowManager* pWm)
				: WtfEngine::GameState(), mrWinMgr(pWm)	{};
	};
};


#endif
